package com.gitee.feizns.utils.reflect;

import java.lang.reflect.Method;

/**
 * @author feizns
 * @since 2019/5/15
 */
public abstract class MethodUtils {

    /**
     * 获取方法
     * @param obj
     * @param name
     * @return
     */
    public static final Method getDeclaredMethod(Object obj, String name, Class<?>... parameterTypes) {
        return getDeclaredMethod(obj.getClass(), name, parameterTypes);
    }

    /**
     * 获取方法
     * @param type
     * @param name
     * @param parameterTypes
     * @return
     */
    public static final Method getDeclaredMethod(Class<?> type, String name, Class<?>... parameterTypes) {
        while ( type != null ) {
            try {
                return type.getDeclaredMethod(name, parameterTypes);
            } catch (NoSuchMethodException e) {
                type = type.getSuperclass();
            }
        }
        return null;
    }

    /**
     * 获取公共方法
     * @param obj
     * @param name
     * @param parameterTypes
     * @return
     */
    public static final Method getMethod(Object obj, String name, Class<?>... parameterTypes) {
        return getMethod(obj.getClass(), name, parameterTypes);
    }

    /**
     * 获取公共方法
     * @param type
     * @param name
     * @param parameterTypes
     * @return
     */
    public static final Method getMethod(Class<?> type, String name, Class<?>... parameterTypes) {
        try {
            return type.getMethod(name, parameterTypes);
        } catch (NoSuchMethodException e) {
            return null;
        }
    }

    /**
     * 调用方法
     * @param obj
     * @param name
     * @param params
     * @return
     */
    public static final Object invoke(Object obj, String name, Object... params) {
        try {
            return obj.getClass().getMethod(name, ClassUtils.getClasses(params)).invoke(obj, params);
        } catch (ReflectiveOperationException e) {
            throw new RuntimeException(e);
        }
    }

}
